package ru.ifmo.thesis.gp;

import java.util.ArrayList;
import java.util.List;

import org.jgap.BaseGene;
import org.jgap.Configuration;
import org.jgap.Gene;
import org.jgap.InvalidConfigurationException;
import org.jgap.RandomGenerator;
import org.jgap.UnsupportedRepresentationException;

import ru.ifmo.thesis.domain.Job;
import ru.ifmo.thesis.domain.Worker;

public class WorkPlanGene extends BaseGene {

	private static final long serialVersionUID = 1L;
	
	private final Worker aWorker;

	private List<Job> gene;
	
	public WorkPlanGene(Configuration a_configuration, Worker associatedWorker)
			throws InvalidConfigurationException {
		super(a_configuration);
		this.gene = new ArrayList<Job>();
		this.aWorker = associatedWorker;
	}

	@Override
	protected Object getInternalValue() {
		return gene;
	}

	@Override
	protected Gene newGeneInternal() {
		WorkPlanGene result;
		try {
			result = new WorkPlanGene(getConfiguration(), this.aWorker);
		} catch (InvalidConfigurationException e) {
			throw new RuntimeException(e);
		}
		
		result.gene = new ArrayList<Job>(this.gene);
		return result;
	}

	@Override
	public void applyMutation(int index, double a_percentage) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String getPersistentRepresentation()
			throws UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	public Worker getAssociatedWorker() {
		return aWorker;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public void setAllele(Object value) {
		this.gene = (ArrayList<Job>) value;
	}

	@Override
	public void setToRandomValue(RandomGenerator generator) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValueFromPersistentRepresentation(String a_representation)
			throws UnsupportedOperationException,
			UnsupportedRepresentationException {
		throw new UnsupportedOperationException();
	}

	@Override
	public int compareTo(Object o) {
		if (!(o instanceof WorkPlanGene)) {
			throw new AssertionError("Uncomparable types: " + o.getClass() 
					+ " and " + this.getClass());
		}
		
		WorkPlanGene other = (WorkPlanGene) o;
		
		if (other.gene.equals(this.gene)) {
			return 0;
		} 
		
		if (this.gene.size() < other.gene.size()) {
			return -1;
		} else {
			return 1;
		}
	}
}
